/***
 * any : 任意类型
 * number: 数字类型
 * string: 字符串类型
 * boolean: boolean类型
 * 默认情况下null和undefined是所有类型的子类型。
   Never
 */

// ts 基本类型 (ts做类型约束)
let num: number = 1
// num = '1'
let str: string = '123'
let boo: boolean = true
let n = null
n = 123
let not = undefined

/**
 * @name [Array]
 * @name [type-类型别名]
 */
// 引用类型 array {} function

const arr: (string | number | boolean | null)[] = [1, '6', null, true]
// arr[4] = undefined

// 元组：就是把数组中的每一项都一一对应好类型
const brr: [number, boolean, string] = [1, true, '5']
// type 类型别名(当类型比较多的时候，类型别名type 可以帮助我们提取出来一个类型集合，方便复用)
type ArrType = string | number | boolean | null | undefined | Object

const crr: ArrType[] = [1, '6', null, true]

const drr: ArrType[] = [undefined, null]

const err: ArrType[] = [1, 2, 3, 4, 5, { id: 1, name: 'devin' }]

/**
 * @name Object
 * @name [interface：接口]
 */
// 对象

// 接口 interface 也可以帮助你提取多个类型的一个集合
interface PersonType {
  id: string
  name: string
  gender: number
  address: string
  phone: string
  avtar: string
}

const person: PersonType = {
  id: '1405',
  name: 'devin',
  gender: 1,
  address: '山西省晋城市',
  phone: '13263262903',
  avtar: '1.png',
}

// 接口可以做继承 帮助你优化类型集合的代码
interface StudentType extends PersonType {
  friend: string
}

const student: StudentType = {
  friend: 'girl',
  id: '1405',
  name: 'devin',
  gender: 1,
  address: '山西省晋城市',
  phone: '13263262903',
  avtar: '1.png',
}

/**
 * @name function
 * 1. 参数 对参数注解
 * 2. 返回值 对返回值注解
 *
 * void: 空
 */

const frr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

// const auto = (page: number, size: number): number[] => {
//   return frr.slice((page - 1) * size, page * size)
// }

// let it = auto(1, 5)
// console.log(it, 'it')

interface AutoParamsType {
  page: number
  size: number
  avtar: string
}

const auto = ({ page, size }: AutoParamsType) => {
  return frr.slice((page - 1) * size, page * size)
}

let it = auto({ page: 1, size: 5, avtar: '1.png' })
console.log(it, 'it')

// 翻转输入和输出

/**
 *
 * @name [泛型] <number, string>
 */
// 泛型 （泛指的类型）
function reverArr<T, U>(params: [T, U]): [U, T] {
  return [params[1], params[0]]
}

let it1 = reverArr<number, string>([1, '2']) // ['2',1]
let it2 = reverArr<string, number>(['2', 1]) // ['2',1]
let it3 = reverArr<boolean, number>([true, 1]) // ['2',1]

/**
 *
 * @name [class构造函数语法糖]
 *
 */

interface AnimatePropsType {
  name: string
  address: string
  avatar: string
  say: string
}

// class Animate {
//   // 声明，才能使用
//   // animateProps: AnimatePropsType
//   name: string
//   address: string
//   avatar: string
//   sayMsg: string
//   constructor(props: AnimatePropsType) {
//     this.name = props.name
//     this.address = props.address
//     this.avatar = props.avatar
//     this.sayMsg = props.say
//     // this.animateProps.name = props.name
//   }

//   say() {
//     return this.sayMsg
//   }
// }

// let dog = new Animate({ name: 'dog', address: 'north', avatar: '🐶', say: '汪汪' })
// let cat = new Animate({ name: 'dog', address: 'north', avatar: '🐱', say: '喵喵' })

// let d = dog.say()
// console.log(d, 'd')

/**
 *
 * 定义两种类型：
 * 1. 成功返回模型
 * 2. 失败返回模型
 *
 * code: 1 // 成功 -1 失败
 * msg: success / fail
 * data: []
 *
 */

class Base {
  data: any
  msg: string
  constructor(data: any, msg: string) {
    this.data = data
    this.msg = msg
  }
}

class SuccessModel extends Base {
  code: number
  constructor(data: any, msg: string) {
    super(data, msg) // 执行超类。调用超类
    this.code = 1
  }
}

class FailModel extends Base {
  code: number
  constructor(data: any, msg: string) {
    super(data, msg)
    this.code = -1
  }
}

let s = new SuccessModel(['hello world'], 'success')
let f = new FailModel(null, 'faile')

console.log(s)
console.log(f)
